﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;

namespace JN.Utility
{
    public class HiPerfTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(
            out long lpPerformanceCount);

        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(
            out long lpFrequency);

        
        private Stopwatch _watch; 
        private bool _isSupportHiPerfTimer = false; 
        private long _startTime, _stopTime;
        private long _freq;
        private Stopwatch _watch2 ;


        // 构造函数
        public HiPerfTimer()
        {
            _startTime = 0;
            _stopTime = 0;
            _isSupportHiPerfTimer = true;
            if (QueryPerformanceFrequency(out _freq) == false)
            {
                // 不支持高性能计数器
                _isSupportHiPerfTimer = false;
            }
            else
            {
                _watch = new Stopwatch();
                _watch2 = new Stopwatch();
            }
        }

        // 开始计时器
        public void Start()
        {
            // 来让等待线程工作
            Thread.Sleep(0);

            if (_isSupportHiPerfTimer)
            {
                QueryPerformanceCounter(out _startTime);
                _startTime = (long)(_startTime * 1000.0 / _freq + 0.5); 
            }
            else 
            {
                _watch.Start(); 
                _startTime = _watch.ElapsedMilliseconds; 
            }
        }

        // 停止计时器
        public void Stop()
        {
            if (_isSupportHiPerfTimer)
            {
                QueryPerformanceCounter(out _stopTime);
                _stopTime = (long)(_stopTime * 1000.0 / _freq + 0.5);
            }
            else
            {
                _watch.Stop();
                _stopTime = _watch.ElapsedMilliseconds; 
            }
        }

        // 返回计时器经过时间(单位：毫秒)
        public double Duration
        {
            get
            {
                return (double)(_stopTime - _startTime) ;
            }
        }

        public void HoldingTime(float millisecond )
        {

            //Thread.Sleep((int)(millisecond) ); 
            long time1 = 0;
            long time2 = 0;
            float duration = 0;

            if (_isSupportHiPerfTimer)
            {
                QueryPerformanceCounter(out time1);
            }
            else
            {
                _watch2.Start();
                time1 = _watch2.ElapsedMilliseconds;
            }

            while (duration <= millisecond)
            {
                if (_isSupportHiPerfTimer)
                {
                    QueryPerformanceCounter(out time2);
                    duration = (float)((time2 - time1) * 1000.0 / _freq);
                }
                else
                {
                    time2 = _watch2.ElapsedMilliseconds;
                    duration = time2 - time1;
                }
            }
        }


    }
}